package com.ggy.ggyaiagent.controller;

import com.ggy.ggyaiagent.agent.model.GGYManus;
import com.ggy.ggyaiagent.app.LoveApp;
import com.ggy.ggyaiagent.chatmemory.RedisChatMemory;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import reactor.core.publisher.Flux;

@RestController
@RequestMapping("/ai")
public class AiContorller {
    private final Map<String, SseEmitter> chatEmitters = new ConcurrentHashMap<>();
    @Resource
    private LoveApp loveApp;
    @Resource
    private ToolCallbackProvider toolCallbackProvider;
    @Resource
    private ChatModel dashscopeChatModel;
    @Resource
    private ToolCallback[] allTools;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;


    @GetMapping("/travel_guide/chat/sync")
    public String doChatWithLoveAppSync(String message,String chatId){
        return loveApp.doChat("message",chatId);
    }

    /**
     * 停止回答
     * @param chatId
     * @return
     */
    @GetMapping(value = "/travel_guide/chat/stop")
    public ResponseEntity<String> stopChat(@RequestParam String chatId) {
        SseEmitter emitter = chatEmitters.get(chatId);
        if (emitter != null) {
            emitter.complete();
            chatEmitters.remove(chatId);
            return ResponseEntity.ok("Chat stopped successfully");
        }
        return ResponseEntity.notFound().build();
    }

    @GetMapping(value="/travel_guide/chat/sse",produces= MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> doCHatWithLoveAppSSE(String message,String chatId){
        return loveApp.doChatByStream(message,chatId);
    }

    @GetMapping(value = "/travel_guide/chat/sse")
    public Flux<ServerSentEvent<String>> doChatWithLoveAppSSE(String message,String chatId){
        return loveApp.doChatByStream(message, chatId)
                .map(chunk -> ServerSentEvent.<String>builder()
                        .data(chunk)
                        .build());
    }
    @GetMapping(value = "/travel_guide/chat/sse/emitter")
    public SseEmitter doChatWithLoveAppSseEmitter(String message,String chatId){
        //创建一个超时时间较长的 SseEmitter
        SseEmitter emitter = new SseEmitter(180000L);//3分钟超时
        chatEmitters.put(chatId, emitter);
        //获取 Flux 数据流并直接订阅
        loveApp.doChatByStream(message, chatId)
                .subscribe(
                        //处理每条信息
                        chunk ->{
                            try{
                                emitter.send(chunk);
                            } catch (Exception e) {
                                emitter.completeWithError(e);
                            }
                        },
                        //处理错误、
error -> {
                            emitter.completeWithError(error);
                            chatEmitters.remove(chatId);
                        },
                        //处理完成
                        emitter::complete
                );
        return emitter;
    }

    /**
     * 流式调用 Manus 超级智能体
     * @param message
     * @return
     */
    @GetMapping(value = "/manus/chat")
  public SseEmitter doChatWithManus(String message,String chatId){

      GGYManus ggyManus = new GGYManus(toolCallbackProvider, allTools,dashscopeChatModel,redisTemplate);
        SseEmitter sseEmitter = ggyManus.runStream(message,chatId );
        chatEmitters.put(chatId, sseEmitter);
        return sseEmitter;
  }
  @GetMapping(value = "/chat/memory/redis")
  public List<Message> getRedisChatMemoryList(String chatId){
        return new RedisChatMemory(redisTemplate).findByConversationId(chatId);
  }

}




















